package com.settlement.system.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.settlement.system.common.constant.SystemConstants;
import com.settlement.system.common.model.Option;
import com.settlement.system.common.util.StringUtils;
import com.settlement.system.mapper.SysAccountingProjectMapper;
import com.settlement.system.model.entity.SysAccessory;
import com.settlement.system.model.entity.SysAccountingProject;
import com.settlement.system.model.entity.SysPlatform;
import com.settlement.system.model.entity.SysSubjects;
import com.settlement.system.model.form.AccountProjectForm;
import com.settlement.system.model.query.AccountingProjectPageQuery;
import com.settlement.system.model.vo.SysAccountingProjectVO;
import com.settlement.system.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 记账项目配置 服务实现类
 * </p>
 *
 * @author huangrensen
 * @since 2023-09-08
 */
@Service
@RequiredArgsConstructor
public class SysAccountingProjectServiceImpl extends ServiceImpl<SysAccountingProjectMapper, SysAccountingProject> implements SysAccountingProjectService {

    private final SysSubjectsService sysSubjectsService;

    private final SysPlatformService sysPlatformService;

    private final SysAccessoryService sysAccessoryService;

    private final RedisTemplate redisTemplate;

    private final SysDictService sysDictService;

    @Override
    public Page<SysAccountingProjectVO> getPage(AccountingProjectPageQuery queryParams) {
        // 查询参数
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        String keywords = queryParams.getKeywords();
        List<SysPlatform> sysPlatformList = sysPlatformService.list();
        // 查询数据
        Page<SysAccountingProject> accountingProjectPage = this.page(new Page<>(pageNum, pageSize), new LambdaQueryWrapper<SysAccountingProject>()
                .eq(StringUtils.hasText(queryParams.getBillSystemPlatformCode()), SysAccountingProject::getBillSystemPlatformCode, queryParams.getBillSystemPlatformCode())
                .eq(StringUtils.hasText(keywords), SysAccountingProject::getAccountingProjectName, keywords).orderByDesc(SysAccountingProject::getUpdateTime));
        Page<SysAccountingProjectVO> projectVOPage = new Page<>();
        BeanUtils.copyProperties(accountingProjectPage, projectVOPage, "records");
        List<String> codes = new ArrayList<>();
        for (SysAccountingProject record : accountingProjectPage.getRecords()) {
            if (StringUtils.hasText(record.getLastCode())) {
                codes.add(record.getLastCode());
            }
            if (StringUtils.hasText(record.getOtherLastCode())) {
                codes.add(record.getOtherLastCode());
            }
        }
        List<SysSubjects> sysSubjects;
        if (codes.size() == 0) {
            sysSubjects = new ArrayList<>();
        }else{
            sysSubjects = sysSubjectsService.list(new LambdaQueryWrapper<SysSubjects>().in(SysSubjects::getLastCode, codes));
        }
        List<SysAccountingProjectVO> projectVOS = new ArrayList<>();
        for (SysAccountingProject record : accountingProjectPage.getRecords()) {
            SysAccountingProjectVO vo = new SysAccountingProjectVO();
            BeanUtils.copyProperties(record, vo, "accessory", "otherAccessory");
            if (StringUtils.hasText(record.getAccessory())) {
                vo.setAccessory(JSONObject.parseObject(record.getAccessory(), Map.class));
            }
            if (StringUtils.hasText(record.getOtherAccessory())) {
                vo.setOtherAccessory(JSONObject.parseObject(record.getOtherAccessory(), Map.class));
            }
            sysPlatformList.stream().filter(sysCompany -> sysCompany.getReconciliationSystemCode().equals(record.getBillSystemPlatformCode())).findFirst().ifPresent(sysCompany -> vo.setBillSystemPlatformName(sysCompany.getReconciliationSystemName()));
            // 发生方
            sysSubjects.stream().filter(sysSubject -> sysSubject.getLastCode().equals(record.getLastCode())).findFirst().ifPresent(sysSubject -> {
                vo.setFirstCode(sysSubject.getFirstCode());
                vo.setFirstName(sysSubject.getFirstName());
                vo.setLastName(sysSubject.getLastName());
                vo.setAccountingProject(sysSubject.getAccountingProject());
            });
            // 对方
            sysSubjects.stream().filter(sysSubject -> sysSubject.getLastCode().equals(record.getOtherLastCode())).findFirst().ifPresent(sysSubject -> {
                vo.setOtherFirstCode(sysSubject.getFirstCode());
                vo.setOtherFirstName(sysSubject.getFirstName());
                vo.setOtherLastName(sysSubject.getLastName());
                vo.setOtherAccountingProject(sysSubject.getAccountingProject());
            });
            projectVOS.add(vo);
        }
        projectVOPage.setRecords(projectVOS);
        return projectVOPage;
    }

    @Override
    @SuppressWarnings("unchecked")
    public SysAccountingProject getListByAccountingProjectName(String platform, String accountingProjectName) {
        Object value = redisTemplate.opsForValue().get(SystemConstants.ACCOUNTING_PROJECT.formatted(platform, accountingProjectName));
        if (value != null) {
            return (SysAccountingProject) value;
        }
        List<SysAccountingProject> list = this.list(new LambdaQueryWrapper<SysAccountingProject>().eq(SysAccountingProject::getBillSystemPlatformCode, platform)
                .eq(SysAccountingProject::getAccountingProjectName
                        , accountingProjectName));
        if (list.size() == 0) {
            return null;
        }
        SysAccountingProject sysAccountingProject = list.get(0);
        redisTemplate.opsForValue().set(SystemConstants.ACCOUNTING_PROJECT.formatted(platform, accountingProjectName)
                , sysAccountingProject, 1, TimeUnit.HOURS);
        return sysAccountingProject;
    }

    @Override
    @SuppressWarnings("unchecked")
    public boolean saveAccountingProject(AccountProjectForm accountProjectForm) {
        long count;
        if (accountProjectForm.getId() == null) {
            count = this.count(new LambdaQueryWrapper<SysAccountingProject>().eq(SysAccountingProject::getBillSystemPlatformCode, accountProjectForm.getBillSystemPlatformCode()
            ).eq(SysAccountingProject::getAccountingProjectName,
                    accountProjectForm.getAccountingProjectName()));
        } else {
            count = this.count(new LambdaQueryWrapper<SysAccountingProject>().eq(SysAccountingProject::getAccountingProjectName, accountProjectForm.getAccountingProjectName()).ne(SysAccountingProject::getId, accountProjectForm.getId()));
        }
        Assert.isTrue(count == 0,
                "当前平台的电商平台账单项目【%s】已存在".formatted(accountProjectForm.getAccountingProjectName()));
        SysAccountingProject sysAccountingProject;
        if (accountProjectForm.getId() != null) {
            sysAccountingProject = this.getById(accountProjectForm.getId());
        } else {
            sysAccountingProject = new SysAccountingProject();
        }
        BeanUtils.copyProperties(accountProjectForm, sysAccountingProject, "id", "accessory", "otherAccessory", "fundingProjects");
        if (StringUtils.hasText(accountProjectForm.getBorrowing()) && StringUtils.hasText(accountProjectForm.getOtherBorrowing())) {
            Assert.isTrue(!Objects.equals(accountProjectForm.getBorrowing(), accountProjectForm.getOtherBorrowing()),
                    "发生方和对方科目的借贷方向一致，不允许保存");
        }
        // 把字典配置项转成字符串保存
        if(Objects.nonNull(accountProjectForm.getAccessory())){
            sysAccountingProject.setAccessory(JSONObject.toJSONString(accountProjectForm.getAccessory()));
        }
        if(Objects.nonNull(accountProjectForm.getOtherAccessory())){
            sysAccountingProject.setOtherAccessory(JSONObject.toJSONString(accountProjectForm.getOtherAccessory()));
        }
        if(Objects.nonNull(accountProjectForm.getFundingProjects())){
            sysAccountingProject.setFundingProjectsStr(JSONObject.toJSONString(accountProjectForm.getFundingProjects()));
        }
        // 删除缓存
        redisTemplate.delete(SystemConstants.ACCOUNTING_PROJECT.formatted(sysAccountingProject.getBillSystemPlatformCode(), sysAccountingProject.getAccountingProjectName()));
        return this.saveOrUpdate(sysAccountingProject);
    }

    @Override
    public SysAccountingProjectVO getSysAccountingProjectFormData(Long accountingProjectId) {
        SysAccountingProject sysAccountingProject = this.getById(accountingProjectId);
        SysAccountingProjectVO vo = new SysAccountingProjectVO();
        BeanUtils.copyProperties(sysAccountingProject, vo, "accessory", "otherAccessory");
        if (StringUtils.hasText(sysAccountingProject.getAccessory())) {
            vo.setAccessory(JSONObject.parseObject(sysAccountingProject.getAccessory(), Map.class));
        }
        if (StringUtils.hasText(sysAccountingProject.getOtherAccessory())) {
            vo.setOtherAccessory(JSONObject.parseObject(sysAccountingProject.getOtherAccessory(), Map.class));
        }
        if (StringUtils.hasText(sysAccountingProject.getFundingProjectsStr())) {
            vo.setFundingProjects(JSONObject.parseObject(sysAccountingProject.getFundingProjectsStr(), Map.class));
        }
        List<String> codes = new ArrayList<>();
        if (StringUtils.hasText(sysAccountingProject.getLastCode())) {
            codes.add(sysAccountingProject.getLastCode());
        }
        if (StringUtils.hasText(sysAccountingProject.getOtherLastCode())) {
            codes.add(sysAccountingProject.getOtherLastCode());
        }
        List<SysSubjects> sysSubjects;
        if(codes.size() > 0){
            sysSubjects = sysSubjectsService.list(new LambdaQueryWrapper<SysSubjects>().in(SysSubjects::getLastCode, codes));
        }else{
            sysSubjects = new ArrayList<>();
        }
        // 发生方
        sysSubjects.stream().filter(sysSubject -> sysSubject.getLastCode().equals(vo.getLastCode())).findFirst().ifPresent(sysSubject -> {
            vo.setFirstCode(sysSubject.getFirstCode());
            vo.setFirstName(sysSubject.getFirstName());
            vo.setLastName(sysSubject.getLastName());
            vo.setAccountingProject(sysSubject.getAccountingProject());
        });
        // 对方
        sysSubjects.stream().filter(sysSubject -> sysSubject.getLastCode().equals(vo.getOtherLastCode())).findFirst().ifPresent(sysSubject -> {
            vo.setOtherFirstCode(sysSubject.getFirstCode());
            vo.setOtherFirstName(sysSubject.getFirstName());
            vo.setOtherLastName(sysSubject.getLastName());
            vo.setOtherAccountingProject(sysSubject.getAccountingProject());
        });
        return vo;
    }

    @Override
    @SuppressWarnings("unchecked")
    public boolean deleteAccountingProject(String idsStr) {
        Assert.isTrue(StringUtils.hasText(idsStr), "删除的记账项目数据为空");
        List<Long> ids = Arrays.stream(idsStr.split(",")).map(Long::parseLong).collect(Collectors.toList());
        List<SysAccountingProject> list = this.list(new LambdaQueryWrapper<SysAccountingProject>().in(SysAccountingProject::getId, ids));
        for (SysAccountingProject sysAccountingProject : list) {
            redisTemplate.delete(SystemConstants.ACCOUNTING_PROJECT.formatted(sysAccountingProject.getBillSystemPlatformCode(), sysAccountingProject.getAccountingProjectName()));
        }
        return this.removeByIds(ids);
    }

    @Override
    @SuppressWarnings("unchecked")
    public Set<String> updateBatch(List<Map<String, String>> records, List<Map<String, String>> dataAccessoryList) {
        List<String> apportionmentList = Arrays.asList("是", "否");
        List<String> invoiceList = Arrays.asList("票前", "票后");
        List<String> auditList = Arrays.asList("参与", "不参与");
        List<String> accountingList = Arrays.asList("参与", "不参与");
        List<String> payTypeList = Arrays.asList("收入", "支出");
        List<String> borrowList = Arrays.asList("借", "贷");
        Set<String> messages = new HashSet<>();
        List<SysAccountingProject> createList = new ArrayList<>();
        // 业务平台
        List<SysPlatform> platformList = sysPlatformService.list();
        // 末级科目
        List<SysSubjects> subjectsList = sysSubjectsService.list();
        // 辅助项
        List<SysAccessory> sysAccessoryList = sysAccessoryService.findAll();
        if (sysAccessoryList == null || sysAccessoryList.size() == 0) {
            messages.add("系统没有配置到辅助项，导入失败");
            return messages;
        }
        SysAccessory accessory = sysAccessoryList.get(0);
        List<String> accessoryTextList = new ArrayList<>();
        if (StringUtils.hasText(accessory.getAccessoryName1())) {
            accessoryTextList.add(accessory.getAccessoryName1());
        }
        if (StringUtils.hasText(accessory.getAccessoryName2())) {
            accessoryTextList.add(accessory.getAccessoryName2());
        }
        if (StringUtils.hasText(accessory.getAccessoryName3())) {
            accessoryTextList.add(accessory.getAccessoryName3());
        }
        if (StringUtils.hasText(accessory.getAccessoryName4())) {
            accessoryTextList.add(accessory.getAccessoryName4());
        }
        if (StringUtils.hasText(accessory.getAccessoryName5())) {
            accessoryTextList.add(accessory.getAccessoryName5());
        }
        if (StringUtils.hasText(accessory.getAccessoryName6())) {
            accessoryTextList.add(accessory.getAccessoryName6());
        }
        if (StringUtils.hasText(accessory.getAccessoryName7())) {
            accessoryTextList.add(accessory.getAccessoryName7());
        }
        if (StringUtils.hasText(accessory.getAccessoryName8())) {
            accessoryTextList.add(accessory.getAccessoryName8());
        }
        if (StringUtils.hasText(accessory.getAccessoryName9())) {
            accessoryTextList.add(accessory.getAccessoryName9());
        }
        // 检查是否重复
        Set<String> nameList = new HashSet<>();
        String text;
        Map<String, Map<String, String>> accessoryMap;
        Map<String, String> fundMap;
        List<Map<String, String>> filterAccessoryMap;
        for (Map<String, String> record : records) {
            if (!StringUtils.hasText(record.get("电商平台账单项目"))) {
                messages.add("电商平台账单项目不能为空");
                break;
            }
            if (!StringUtils.hasText(record.get("业务平台"))) {
                messages.add("业务平台不能为空");
                break;
            }
            text = record.get("业务平台") + record.get("电商平台账单项目");
            if (nameList.contains(text)) {
                messages.add("业务平台+电商平台账单项目【%s】存在重复数据，导入失败".formatted(text));
            } else {
                nameList.add(text);
            }
        }
        if (messages.size() > 0) {
            return messages;
        }
        List<Option> optionList = sysDictService.listDictOptions(SystemConstants.FUNDING_PROJECT);
        // 创建数据
        for (Map<String, String> record : records) {
            SysAccountingProject sysAccountingProject = new SysAccountingProject();
            sysAccountingProject.setCarrier(record.get("供应商名称"));
            sysAccountingProject.setRate(record.get("税率"));
            sysAccountingProject.setFundingDirection(record.get("资金项目计算方向"));
            if (record.get("电商平台账单项目") == null && !messages.contains("电商平台账单项目不能为空")) {
                messages.add("电商平台账单项目不能为空");
            } else {
                sysAccountingProject.setAccountingProjectName(record.get("电商平台账单项目"));
            }
            SysPlatform sysPlatform = platformList.stream().filter(platform -> platform.getReconciliationSystemName().equals(record.get("业务平台")))
                    .findFirst()
                    .orElse(null);
            if (sysPlatform == null) {
                messages.add("系统找不到对账系统平台名称【%s】的记录".formatted(record.get("业务平台")));
            } else {
                sysAccountingProject.setBillSystemPlatformCode(sysPlatform.getReconciliationSystemCode());
                sysAccountingProject.setBillSystemPlatformName(sysPlatform.getReconciliationSystemName());
            }
            List<Option> options;
            // 来源单据
            if (StringUtils.hasText(record.get("来源单据"))) {
                options = sysDictService.listDictOptions(SystemConstants.SOURCE_ORDER);
                if (options.stream().noneMatch(item -> Objects.equals(item.getValue().toString(), record.get("来源单据")))) {
                    messages.add("系统找不到来源单据【%s】".formatted(record.get("来源单据")));
                } else {
                    sysAccountingProject.setOrderType(record.get("来源单据"));
                }
            }
            if (StringUtils.hasText(record.get("借贷方向")) && !borrowList.contains(record.get("借贷方向"))) {
                messages.add("借贷方向有以下两个值：借、贷。请调整表格数据");
            }
            if (StringUtils.hasText(record.get("对方借贷方向")) && !borrowList.contains(record.get("对方借贷方向"))) {
                messages.add("对方借贷方向有以下两个值：借、贷。请调整表格数据");
            }
            // 发生方
            SysSubjects sysSubjectJie = null;
            if (StringUtils.hasText(record.get("末级科目编码"))) {
                sysSubjectJie = subjectsList.stream().filter(subject -> subject.getLastCode().equals(record.get("末级科目编码")))
                        .findFirst()
                        .orElse(null);
                if (sysSubjectJie == null) {
                    messages.add("系统没有维护末级科目编码【%s】".formatted(record.get("末级科目编码")));
                } else {
                    sysAccountingProject.setLastCode(sysSubjectJie.getLastCode());
                    sysAccountingProject.setLastName(sysSubjectJie.getLastName());
                    sysAccountingProject.setFirstCode(sysSubjectJie.getFirstCode());
                    sysAccountingProject.setFirstName(sysSubjectJie.getFirstName());
                    sysAccountingProject.setAccountingProject(sysSubjectJie.getAccountingProject());
                    if (StringUtils.hasText(record.get("借贷方向"))) {
                        sysAccountingProject.setBorrowing(record.get("借贷方向"));
                    } else {
                        sysAccountingProject.setBorrowing(sysSubjectJie.getBorrowing());
                    }
                }
            }
            // 对方
            SysSubjects sysSubjectDai = null;
            if (StringUtils.hasText(record.get("对方末级科目编码"))) {
                sysSubjectDai = subjectsList.stream().filter(subject -> subject.getLastCode().equals(record.get("对方末级科目编码")))
                        .findFirst()
                        .orElse(null);
                if (sysSubjectDai == null) {
                    messages.add("系统没有维护末级科目编码【%s】".formatted(record.get("对方末级科目编码")));
                } else {
                    sysAccountingProject.setOtherLastCode(sysSubjectDai.getLastCode());
                    sysAccountingProject.setOtherLastName(sysSubjectDai.getLastName());
                    sysAccountingProject.setOtherFirstCode(sysSubjectDai.getFirstCode());
                    sysAccountingProject.setOtherFirstName(sysSubjectDai.getFirstName());
                    sysAccountingProject.setOtherAccountingProject(sysSubjectDai.getAccountingProject());
                    if (StringUtils.hasText(record.get("对方借贷方向"))) {
                        sysAccountingProject.setOtherBorrowing(record.get("对方借贷方向"));
                    } else {
                        sysAccountingProject.setOtherBorrowing(sysSubjectDai.getBorrowing());
                    }
                }
            }
            if (Objects.nonNull(sysSubjectJie) && Objects.nonNull(sysSubjectDai)) {
                // 判断借贷方向是否一致
                if (Objects.equals(sysAccountingProject.getBorrowing(), sysAccountingProject.getOtherAccountingProject())) {
                    messages.add("发生方的借贷方向【%s】和对方的借贷方向【%s】一致，请修改".formatted(sysAccountingProject.getBorrowing(),
                            sysAccountingProject.getOtherAccountingProject()));
                }
            }
            if (StringUtils.hasText(record.get("是否分摊")) && !apportionmentList.contains(record.get("是否分摊"))) {
                messages.add("是否分摊有以下两个值：是、否。请调整表格数据");
            } else {
                sysAccountingProject.setApportionment(record.get("是否分摊"));
            }
            if (StringUtils.hasText(record.get("票前票后")) && !invoiceList.contains(record.get("票前票后"))) {
                messages.add("票前票后有以下两个值：票前、票后。请调整表格数据");
            } else {
                sysAccountingProject.setInvoice(record.get("票前票后"));
            }
            if (StringUtils.hasText(record.get("稽核标识")) && !auditList.contains(record.get("稽核标识"))) {
                messages.add("稽核标识有以下两个值：参与、不参与。请调整表格数据");
            } else {
                sysAccountingProject.setAudit(record.get("稽核标识"));
            }
            if (StringUtils.hasText(record.get("是否参与记账")) && !accountingList.contains(record.get("是否参与记账"))) {
                messages.add("是否参与记账有以下两个值：参与、不参与。请调整表格数据");
            } else {
                sysAccountingProject.setAccounting(record.get("是否参与记账"));
            }
            if (StringUtils.hasText(record.get("收支方向"))) {
                if (!payTypeList.contains(record.get("收支方向"))) {
                    messages.add("收支方向有以下两个值：收入、支出。请调整表格数据");
                } else {
                    sysAccountingProject.setPayType(record.get("收支方向"));
                }
            }
            // 发生方
            accessoryMap = new HashMap<>();
            filterAccessoryMap = dataAccessoryList.stream().filter(item ->
                    Objects.equals(StringUtils.getString(item.get("业务平台"), null), StringUtils.getString(record.get("业务平台"), null)) &&
                            Objects.equals(StringUtils.getString(item.get("电商平台账单项目"), null), StringUtils.getString(record.get("电商平台账单项目"), null))).toList();
            if (filterAccessoryMap.size() > 0) {
                Map<String, String> storeDataAccessory;
                for (Map<String, String> sysAccessory : filterAccessoryMap) {
                    String storeName = sysAccessory.get("电商平台店铺名称");
                    storeDataAccessory = new HashMap<>();
                    for (String key : sysAccessory.keySet()) {
                        storeDataAccessory.put(key, sysAccessory.get(key));
                    }
                    accessoryMap.put(storeName, storeDataAccessory);

                }
            }
            sysAccountingProject.setAccessory(JSONObject.toJSONString(accessoryMap));
            // 对方
            accessoryMap = new HashMap<>();
            if (filterAccessoryMap.size() > 0) {
                Map<String, String> storeDataAccessory;
                for (Map<String, String> sysAccessory : filterAccessoryMap) {
                    String storeName = sysAccessory.get("电商平台店铺名称");
                    storeDataAccessory = new HashMap<>();
                    for (String key : sysAccessory.keySet()) {
                        storeDataAccessory.put(key, sysAccessory.get("对方" + key));
                    }
                    accessoryMap.put(storeName, storeDataAccessory);

                }
            }
            sysAccountingProject.setOtherAccessory(JSONObject.toJSONString(accessoryMap));
            // 资金项目类别配置
            fundMap = new HashMap<>();
            for (Option option : optionList) {
                if(StringUtils.hasText(record.get(option.getLabel()))){
                    Assert.isTrue(record.get(option.getLabel()).contains("+") || record.get(option.getLabel()).contains("-"), "资金项目类别【%s】没有配置计算方向，例子：提现+ 提现-".formatted(option.getLabel()));
                }
                fundMap.put(option.getLabel(), record.get(option.getLabel()));
            }
            sysAccountingProject.setFundingProjectsStr(JSONObject.toJSONString(fundMap));
            // 加入列表
            createList.add(sysAccountingProject);
        }
        if (messages.size() == 0) {
            List<String> accountingProjectNameList = createList.stream().map(SysAccountingProject::getAccountingProjectName).distinct().toList();
            // 查出相同的账单项目
            List<SysAccountingProject> accountingProjects = this.list(new LambdaQueryWrapper<SysAccountingProject>().in(SysAccountingProject::getAccountingProjectName, accountingProjectNameList));
            SysAccountingProject accountingProject;
            for (SysAccountingProject project : createList) {
                accountingProject = accountingProjects.stream().filter(item -> Objects.equals(item.getBillSystemPlatformCode(), project.getBillSystemPlatformCode()) && Objects.equals(item.getAccountingProjectName(), project.getAccountingProjectName())).findFirst().orElse(null);
                if (Objects.nonNull(accountingProject)) {
                    BeanUtils.copyProperties(project, accountingProject, "id");
                    this.updateById(accountingProject);
                } else {
                    this.save(project);
                }
            }
            // 删除缓存
            for (SysAccountingProject sysAccountingProject : createList) {
                redisTemplate.delete(SystemConstants.ACCOUNTING_PROJECT.formatted(sysAccountingProject.getBillSystemPlatformCode(), sysAccountingProject.getAccountingProjectName()));
            }
        }
        return messages;
    }

    @Override
    public List<SysAccountingProjectVO> getList(String idsStr) {
        List<SysAccountingProjectVO> projectVOList = new ArrayList<>();
        if (!StringUtils.hasText(idsStr)) {
            return projectVOList;
        }
        List<SysPlatform> sysPlatformList = sysPlatformService.list();
        List<Long> ids = Arrays.stream(idsStr.split(",")).map(Long::parseLong).collect(Collectors.toList());
        List<SysAccountingProject> list = this.list(new LambdaQueryWrapper<SysAccountingProject>().in(SysAccountingProject::getId, ids));
        List<String> codes = list.stream().map(SysAccountingProject::getLastCode).distinct().toList();
        List<SysSubjects> sysSubjects =
                sysSubjectsService.list(new LambdaQueryWrapper<SysSubjects>().in(SysSubjects::getLastCode, codes));
        for (SysAccountingProject record : list) {
            SysAccountingProjectVO vo = new SysAccountingProjectVO();
            BeanUtils.copyProperties(record, vo, "accessory", "otherAccessory");
            if (StringUtils.hasText(record.getAccessory())) {
                vo.setAccessory(JSONObject.parseObject(record.getAccessory(), Map.class));
            }
            if (StringUtils.hasText(record.getOtherAccessory())) {
                vo.setOtherAccessory(JSONObject.parseObject(record.getOtherAccessory(), Map.class));
            }
            if (StringUtils.hasText(record.getFundingProjectsStr())) {
                vo.setFundingProjects(JSONObject.parseObject(record.getFundingProjectsStr(), Map.class));
            }
            sysPlatformList.stream().filter(sysCompany -> sysCompany.getReconciliationSystemCode().equals(record.getBillSystemPlatformCode())).findFirst().ifPresent(sysCompany -> vo.setBillSystemPlatformName(sysCompany.getReconciliationSystemName()));
            // 发生方
            sysSubjects.stream().filter(sysSubject -> sysSubject.getLastCode().equals(record.getLastCode())).findFirst().ifPresent(sysSubject -> {
                vo.setFirstCode(sysSubject.getFirstCode());
                vo.setFirstName(sysSubject.getFirstName());
                vo.setLastName(sysSubject.getLastName());
                vo.setAccountingProject(sysSubject.getAccountingProject());
            });
            // 对方
            sysSubjects.stream().filter(sysSubject -> sysSubject.getLastCode().equals(record.getOtherLastCode())).findFirst().ifPresent(sysSubject -> {
                vo.setOtherFirstCode(sysSubject.getFirstCode());
                vo.setOtherFirstName(sysSubject.getFirstName());
                vo.setOtherLastName(sysSubject.getLastName());
                vo.setOtherAccountingProject(sysSubject.getAccountingProject());
            });
            projectVOList.add(vo);
        }
        return projectVOList;
    }
}
